package com.bezdelnick.forum.web.page;

import com.bezdelnick.forum.domain.Question;
import com.bezdelnick.forum.domain.Type;
import com.bezdelnick.forum.mail.MailFactory;
import com.bezdelnick.forum.mail.type.AbstractMail;
import com.bezdelnick.forum.repository.FileSystemFolderRepository;
import com.bezdelnick.forum.service.ForumService;
import com.bezdelnick.forum.web.model.AddingQuestion;
import com.bezdelnick.forum.web.page.template.UserMainMenuTemplate;
import com.bezdelnick.forum.web.panel.ModeratorMainMenuPanel;
import com.bezdelnick.forum.web.resource.ImageFromFileSystemReference;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.authroles.authorization.strategies.role.annotations.AuthorizeInstantiation;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.*;
import org.apache.wicket.markup.html.image.Image;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.IRequestParameters;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.request.resource.ResourceReference;
import org.apache.wicket.request.resource.SharedResourceReference;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.springframework.web.util.HtmlUtils;

/**
 * Created by IntelliJ IDEA.
 * User: Bezdelnick
 * Date: 21.07.12
 * Time: 18:39
 * To change this template use File | Settings | File Templates.
 */
@AuthorizeInstantiation({"ROLE_USER", "ROLE_MODER"})
public class AddQuestionPage extends UserMainMenuTemplate {
    private static final Logger LOGGER = LoggerFactory.getLogger(AddQuestionPage.class);

    @SpringBean
    @SuppressWarnings("unused")
    private ForumService forumService;

    private AddQuestionForm form;
    final ModalWindow modalWindowUploadImage;

    private ForumService.MODE mode = ForumService.MODE.USER;
    private Question deliveryQuestion = null;

    private String imageUrl = "";

    public AddQuestionPage() {
        this(new PageParameters());
    }

    public AddQuestionPage(PageParameters parameters) {
        this.getPageParameters().mergeWith(parameters);

        if (forumService.hasModeratorAuthority() && !this.getPageParameters().get("action").isNull() && !this.getPageParameters().get("id").isNull()) {
            if (this.getPageParameters().get("action").toString().equals(ModeratorPage.ACTION_EDIT)) {
                this.mode = ForumService.MODE.MODER;

                long id = this.getPageParameters().get("id").toLong();
                if (forumService.getQuestionDao().getQuestionById(id) != null)
                    deliveryQuestion = forumService.getQuestionDao().getQuestionById(id);
            }
        }

        if (forumService.hasModeratorAuthority()) {
            remove("mainPanel");
            add(new ModeratorMainMenuPanel("mainPanel"));
        }

        // add body component
        form = new AddQuestionForm("form");
        add(form);


        add(modalWindowUploadImage = new ModalWindow("modal1"));
        modalWindowUploadImage.setCookieName("modal-1");
        modalWindowUploadImage.setPageCreator(new ModalWindow.PageCreator() {
            public Page createPage() {
                return new UploadAndInsertContentPage(AddQuestionPage.this.getPageReference(), modalWindowUploadImage);
            }
        });
        modalWindowUploadImage.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
            public void onClose(AjaxRequestTarget target) {
                if (imageUrl.length() > 0) {
                    target.appendJavaScript("pasteImageUrl('" + imageUrl + "');");
                    imageUrl = "";
                }
            }
        });
    }

    private class AddQuestionForm extends Form<AddingQuestion> {
        private static final long serialVersionUID = 1L;

        private String type;
        private String subtype;

        private List<String> typesList;
        private List<String> subtypesList;

        FormComponent<String> tbTitleQuestion;
        public FormComponent<String> taTextQuestion;
        FormComponent<String> ddcTypes;
        FormComponent<String> ddcSubtypes;

        private String textQuestion = "";

        public AddQuestionForm(String id) {
            super(id);
            setModel(new CompoundPropertyModel<AddingQuestion>(new AddingQuestion()));

            this.typesList = forumService.loadTypesNames();
            this.type = this.typesList.get(0);

            // ------------------------------

            tbTitleQuestion = new TextField<String>("title").setRequired(true);
            add(tbTitleQuestion);

            taTextQuestion = new TextArea<String>("text", new PropertyModel(this, "textQuestion"));
            add(taTextQuestion);

            AbstractDefaultAjaxBehavior clickBehavior = new AbstractDefaultAjaxBehavior() {
                @Override
                public void renderHead(Component component, IHeaderResponse response) {
                    String js = "" +
                            "function callWicket(_action) { " +
                            "   var wcall = wicketAjaxGet ('" +
                            "" + getCallbackUrl() + "&action='+_action, " +
                            "       function() { }, " +
                            "       function() { } " +
                            "   ) " +
                            "}";
                    response.renderJavaScript(js, "scriptFromWicket_1");
                }

                @Override
                protected void respond(AjaxRequestTarget target) {
                    IRequestParameters requestParameters = getRequestCycle().getRequest().getRequestParameters();
                    String action = requestParameters.getParameterValue("action").toString();
                    if (action.equals("uploadImage"))
                        modalWindowUploadImage.show(target);
                }
            };
            add(clickBehavior);

            ddcTypes = new DropDownChoice<String>("type", new PropertyModel<String>(this, "type"), new TypesModel()) {
                @Override
                protected boolean wantOnSelectionChangedNotifications() {
                    return true;
                }

                @Override
                protected void onSelectionChanged(String newSelection) {
                    subtype = null;
                }
            };
            ddcTypes.setRequired(true);
            ddcTypes.add(new AjaxFormComponentUpdatingBehavior("onchange") {
                @Override
                protected void onUpdate(AjaxRequestTarget target) {
                    target.add(ddcSubtypes);
                }
            });
            add(ddcTypes);

            ddcSubtypes = new DropDownChoice<String>("subtype", new PropertyModel<String>(this, "subtype"), new SubtypesModel());
            ddcSubtypes.setRequired(true);
            ddcSubtypes.setOutputMarkupId(true);
            add(ddcSubtypes);

            if (mode == ForumService.MODE.MODER) {
                AddingQuestion addingQuestion = new AddingQuestion();
                addingQuestion.setTitle(deliveryQuestion.getTitle());
                addingQuestion.setText(deliveryQuestion.getTextQuestion());
                setModel(new CompoundPropertyModel<AddingQuestion>(addingQuestion));

                this.type = forumService.getTypeDao().getTypeById(deliveryQuestion.getTypeId()).getName();
                this.subtype = forumService.getSubtypeDao().getSubtypeById(deliveryQuestion.getSubtypeId()).getName();
            }
        }

        @Override
        protected void onSubmit() {
            AddingQuestion addingQuestion = getModelObject();

            Question question = new Question();

            if (mode == ForumService.MODE.MODER)
                question.setId(deliveryQuestion.getId());

            question.setTitle(HtmlUtils.htmlEscape(addingQuestion.getTitle()));
            question.setTypeId(
                    forumService.getTypeDao().getTypeByName(
                            ddcTypes.getConvertedInput()
                    ).getId()
            );
            question.setSubtypeId(
                    forumService.getSubtypeDao().getSubtypeByName(
                            ddcSubtypes.getConvertedInput()
                    ).getId()
            );
            question.setTextQuestion(HtmlUtils.htmlUnescape(textQuestion));
            question.setDatePublication(new Date());
            question.setEnabled(true);
            question.setNotificationEmail(true);

            if (mode == ForumService.MODE.MODER)
                question.setUserId(deliveryQuestion.getUserId());
            else
                question.setUserId(forumService.getCurrentAppUser().getId());


            setModelObject(new AddingQuestion());

            // Send mail
            if (mode == ForumService.MODE.USER) {
                AbstractMail addQuestionMail = MailFactory.buildMailFor(Question.class);
                addQuestionMail.setSubject("Programmers forum. You have add a new question.");
                addQuestionMail.setRecipients(new String[]{
                        forumService.getCurrentAppUser().getEmail()
                });
                addQuestionMail.setSender("gofor.broake665@gmail.com");

                if (addQuestionMail.buildContext(question))
                    forumService.getMailSendManager().sendMessage(addQuestionMail);
            }
            // Write data to database
            if (mode == ForumService.MODE.MODER && forumService.hasModeratorAuthority())
                forumService.getQuestionDao().updateQuestion(question);
            else
                forumService.getQuestionDao().insertQuestion(question);

            // Redirecting to Admin page if current user is administrator
            // else redirect to Index Page
            if (mode == ForumService.MODE.MODER && forumService.hasModeratorAuthority())
                redirectToInterceptPage(new ModeratorPage());
            else
                redirectToInterceptPage(new IndexPage());
        }

        public String getTextQuestion() {
            return textQuestion;
        }

        public void setTextQuestion(String textQuestion) {
            this.textQuestion = textQuestion;
        }

        private class TypesModel extends LoadableDetachableModel<List<? extends String>> {
            protected List<? extends String> load() {
                return forumService.loadTypesNames();
            }
        }

        private class SubtypesModel extends LoadableDetachableModel<List<? extends String>> {
            protected List<? extends String> load() {
                Type deliveryType = forumService.getTypeDao().getTypeByName(type);
                List<String> subtypesNames = forumService.loadSubtypesNamesByTypeId(deliveryType.getId());
                return subtypesNames;
            }
        }
    }

    public void setImageUrl(String resourceUrl) {
        imageUrl = resourceUrl;
    }
}